package org.zasadnyy.redlions.players.client.ui;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.zasadnyy.redlions.players.shared.model.TournamentItem;
import org.zasadnyy.redlions.players.shared.remote.PlayersCrudRemote;
import org.zasadnyy.redlions.players.shared.remote.PlayersCrudRemoteAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.smartgwt.client.util.SC;

public class CheckBoxGroup extends Composite {

	private static CheckBoxGroupUiBinder uiBinder = GWT
			.create(CheckBoxGroupUiBinder.class);

	interface CheckBoxGroupUiBinder extends UiBinder<Widget, CheckBoxGroup> {
	}

	private PlayersCrudRemoteAsync servise = GWT
			.create(PlayersCrudRemote.class);

	List<CheckBox> checkBoxes = new ArrayList<CheckBox>();
	List<TournamentItem> allTournaments = new ArrayList<TournamentItem>();

	@UiField
	VerticalPanel checkBoxPanel;

	public CheckBoxGroup() {
		loadTournaments();
		initWidget(uiBinder.createAndBindUi(this));
	}

	public void setCheckBoxes() {

		clearForm();

		for (TournamentItem tournament : allTournaments) {
			CheckBox checkBox = new CheckBox(buildCheckBoxLable(tournament));

			boolean isSelected = false;
			checkBox.setValue(isSelected);

			checkBox.setFormValue(tournament.getId());
			checkBoxPanel.add(checkBox);
			checkBoxes.add(checkBox);
		}

	}

	private void clearForm() {
		for (CheckBox checkBox : checkBoxes) {
			this.checkBoxPanel.remove(checkBox);
		}
		this.checkBoxes.clear();
	}

	public void setCheckBoxes(final Map<Integer, List<TournamentItem>> map) {
		
		servise.getAllTournaments(new AsyncCallback<List<TournamentItem>>() {

			@Override
			public void onSuccess(List<TournamentItem> result) {
				allTournaments.clear();
				allTournaments.addAll(result);
				
				List<String> touramentIds = extractIds(map);

				clearForm();

				for (TournamentItem tournament : allTournaments) {
					CheckBox checkBox = new CheckBox(buildCheckBoxLable(tournament));

					boolean isSelected = touramentIds.contains(tournament.getId());
					checkBox.setValue(isSelected);

					checkBox.setFormValue(tournament.getId());
					checkBoxPanel.add(checkBox);
					checkBoxes.add(checkBox);
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				SC.say("Things are bad!");
			}
		});

		List<String> touramentIds = extractIds(map);

		clearForm();

		for (TournamentItem tournament : allTournaments) {
			CheckBox checkBox = new CheckBox(buildCheckBoxLable(tournament));

			boolean isSelected = touramentIds.contains(tournament.getId());
			checkBox.setValue(isSelected);

			checkBox.setFormValue(tournament.getId());
			checkBoxPanel.add(checkBox);
			checkBoxes.add(checkBox);
		}
	}

	private List<String> extractIds(Map<Integer, List<TournamentItem>> map) {
		List<String> ids = new ArrayList<String>();
		for (Map.Entry<Integer, List<TournamentItem>> entry : map.entrySet()) {
			for (TournamentItem tournament : entry.getValue()) {
				ids.add(tournament.getId());
			}
		}

		return ids;
	}

	private String buildCheckBoxLable(TournamentItem tournament) {
		StringBuilder lable = new StringBuilder(tournament.getTitle());
		DateTimeFormat df = DateTimeFormat
				.getFormat(PredefinedFormat.YEAR_MONTH);
		Date time = tournament.getTime();
		if (time != null) {
			lable.append(" (").append(df.format(time)).append(")");
		}
		return lable.toString();
	}

	public List<TournamentItem> getSelectedItems() {
		List<TournamentItem> selectedTournamnts = new LinkedList<TournamentItem>();
		for (CheckBox checkBox : checkBoxes) {
			if (checkBox.getValue() == true) {
				String tournamentId = checkBox.getFormValue();
				TournamentItem tournamentForId = getTournamentForId(
						allTournaments, tournamentId);
				if (tournamentForId != null) {
					selectedTournamnts.add(tournamentForId);
				}
			}
		}
		return selectedTournamnts;
	}

	private TournamentItem getTournamentForId(List<TournamentItem> tournaments,
			String tournamentId) {
		for (TournamentItem tournment : tournaments) {
			if (tournamentId.equals(tournment.getId())) {
				return tournment;
			}
		}
		return null;
	}

	private void loadTournaments() {
		servise.getAllTournaments(new AsyncCallback<List<TournamentItem>>() {

			@Override
			public void onSuccess(List<TournamentItem> result) {
				allTournaments.clear();
				allTournaments.addAll(result);
			}

			@Override
			public void onFailure(Throwable caught) {
				SC.say("Things are bad!");
			}
		});
	}

}
